package com.tianji.learning.service.impl;

import com.alibaba.csp.sentinel.util.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.leanring.LearningLessonDTO;
import com.tianji.api.dto.leanring.LearningRecordDTO;
import com.tianji.common.exceptions.DbException;
import com.tianji.common.utils.*;
import com.tianji.learning.domain.dto.LearningRecordFormDTO;
import com.tianji.learning.domain.po.LearningLesson;
import com.tianji.learning.domain.po.LearningRecord;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.enums.SectionType;
import com.tianji.learning.mapper.LearningRecordMapper;
import com.tianji.learning.service.ILearningLessonService;
import com.tianji.learning.service.ILearningRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.utils.LearningRecordDelayTaskCheckHandler;
import groovy.util.logging.Log;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 学习记录表 服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2024-11-11
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LearningRecordServiceImpl extends ServiceImpl<LearningRecordMapper, LearningRecord> implements ILearningRecordService {

    private final ILearningLessonService lessonService;
    private final CourseClient courseClient;
    private final LearningRecordDelayTaskCheckHandler taskHandler;
    @Override
    public LearningLessonDTO queryLearningRecordByCourse(Long courseId) {
        log.info("查询用户指定课程：{}的学习进度", courseId);
        // 1.获取登录用户
        Long userid = UserContext.getUser();
        // 2.查询课表
        LearningLesson lesson = lessonService.lambdaQuery()
                .eq(LearningLesson::getUserId, userid)
                .eq(LearningLesson::getCourseId, courseId)
                .one();
        if (ObjectUtils.isEmpty(lesson)){
            return null;
        }
        // 3.查询学习记录
        List<LearningRecord> records = this.lambdaQuery().eq(LearningRecord::getLessonId, lesson.getId()).list();
        // 4.封装结果
        if (ObjectUtils.isEmpty(records)) {
            return null;
        }
       /* LearningLessonDTO dto = new LearningLessonDTO();
        dto.setId(lesson.getId());
        dto.setLatestSectionId(lesson.getLatestSectionId());
        dto.setRecords(BeanUtils.copyList(records, LearningRecordDTO.class));
        return dto;*/
        //LearningLessonDTO.builder().id().records().latestSectionId()
        return LearningLessonDTO.of(lesson.getId(), lesson.getLatestSectionId(), BeanUtils.copyList(records, LearningRecordDTO.class));
    }

    @Override
    @Transactional
    public void submitLearningRecord(LearningRecordFormDTO formDTO) {
        // 1.处理学习进度数据
        SectionType sectionType = formDTO.getSectionType();
       /* boolean firstFinished = false;

        if (sectionType == SectionType.VIDEO){
            //1.1 处理视频学习记录
            firstFinished.handleVideoRecord(formDTO);
        }else {
            //1.2 处理考试学习记录
            firstFinished.handleExamRecord(formDTO);
        }*/
        boolean firstFinished = sectionType == SectionType.VIDEO ? handleVideoRecord(formDTO):handleExamRecord(formDTO);

        //2.处理课表数据
        handerLearningLesson(formDTO, firstFinished);
    }

    // 2.处理课表数据
    private void handerLearningLesson(LearningRecordFormDTO formDTO, boolean firstFinished) {
        // 1.查询课表数据（已学小结数）
        LearningLesson lesson = lessonService.getById(formDTO.getLessonId());
        AssertUtils.isNotNull(lesson, "课表数据不存在");
        //2.判断是否有新的完成小结
        boolean allLearned=false;
        if (firstFinished){
            //查询课程信息
            CourseFullInfoDTO courseInfo= courseClient.getCourseInfoById(lesson.getCourseId(), false, false);
            AssertUtils.isNotNull(courseInfo, "课程信息不存在");

            //比较课程是否全已学完（已学小结数+1>=总的）
             allLearned = lesson.getLearnedSections() + 1 >= courseInfo.getSectionNum();
            //更新课表状态为已完成
                lesson.setStatus(1);
        }

        //更新课表
        boolean updateRuslt = this.lessonService.lambdaUpdate()
                .set(LearningLesson::getLatestSectionId, formDTO.getSectionId())
                .set(LearningLesson::getLatestSectionId, formDTO.getSectionId())
                .set(firstFinished, LearningLesson::getLearnedSections, lesson.getLearnedSections() + 1)
                //.set(firstFinished,"learned_section=learned_section+1")
                .set(allLearned, LearningLesson::getStatus, LessonStatus.FINISHED)
                .set(lesson.getStatus().equals(LessonStatus.NOT_BEGIN),LearningLesson::getStatus, LessonStatus.LEARNING)
                .eq(LearningLesson::getId, lesson.getId())
                .update();

        if (!updateRuslt){
            throw new DbException("更新课表失败");
        }
    }

    // 2.1 处理考试学习记录数据
    private boolean handleExamRecord(LearningRecordFormDTO formDTO) {
    //1.将DTO转为PO
        LearningRecord record = BeanUtils.copyBean(formDTO, LearningRecord.class);
        //2、填入缺失的数据
        record.setUserId(UserContext.getUser());
        record.setFinished(true);
        record.setFinishTime(formDTO.getCommitTime());

        //3.写入数据库
        boolean save = save(record);
        if (!save){
            throw new DbException("新增考试学习记录失败");
        }
        //4.返回标识
        return true;
    }


    // 2.2 处理视频学习记录数据
    private boolean handleVideoRecord(LearningRecordFormDTO formDTO) {
        //查询旧的学习记录
        LearningRecord oldRecord = this.lambdaQuery()
                .eq(LearningRecord::getSectionId, formDTO.getSectionId())
                .eq(LearningRecord::getUserId, UserContext.getUser()).one();

        //判断旧的学习记录是否存在
        if (ObjectUtils.isEmpty(oldRecord)){
            //如果不存在新增学习记录
            //1.将DTO转为PO
            LearningRecord record = BeanUtils.copyBean(formDTO, LearningRecord.class);
            //2、填入缺失的数据
            record.setUserId(UserContext.getUser());

            //3.写入数据库
            boolean save = save(record);
            if (!save){
                throw new DbException("新增视频学习记录失败");
            }
            //4.返回标识
            return false;

        }

        //如果存在，更新学习记录

        //判断是否是第一次学完当前小结
        //boolean firstFinished = !oldRecord.getFinished() && formDTO.getMoment() * 2 > formDTO.getDuration();
        boolean firstFinished = !oldRecord.getFinished() && formDTO.getMoment() << 1 > formDTO.getDuration();

        //更新学习记录
        oldRecord.setMoment(formDTO.getMoment());
        boolean updateResult = this.lambdaUpdate()
                .set(LearningRecord::getMoment, formDTO.getMoment())
                .set(firstFinished, LearningRecord::getFinished, true)
                .set(firstFinished, LearningRecord::getFinishTime, formDTO.getCommitTime())
                .eq(LearningRecord::getId, oldRecord.getId()).update();

        if (!updateResult){
            throw new DbException("更新视频学习记录失败");
        }
        return false;
    }
}
